/*
 * net_register.c
 *
 *  Created on: 2023年11月6日
 *      Author: fjx
 */
#include "device.h"
#include "app_log.h"
#include "device_nvm.h"
#include "net_register.h"
#include "util.h"
#include "app_hub_api_subsidiary.h"
#include "net_packet.h"

uint8_t invailID[NODE_JOIN_INFO_LENGTH]={0};


void reg_printfInvailID(void)
{
  if(get_net_printf_log() == true){
    DS_app_log_error("IID: ");
    for(uint8_t i=0;i<sizeof(invailID);i++){
        DS_app_log_error("%02x",invailID[i]);
    }
    DS_app_log_error("\n");
  }
}
/********************************************
 *
 * @brief 设置ID到info
 * @param id:   注册的ID
 * @param info: 注册信息
 */

void reg_setIdToInfo(uint8_t id,uint8_t *info)
{
  uint8_t i,j;

  i=id/8;
  j=id%8;


  if(j==0){
    info[i-1] =0x80;
  }
  else {
    info[i] = 1<<(j-1);
  }


}
/*****************************************
 * @brief 获取ID
 * @param x为0~31
 * @param y为位域0~7
 * @param id通过x,y计算得出的ID
 *
 *
 */
bool reg_getInfoId(uint8_t *info,uint8_t x,uint8_t y,uint8_t *id)
{
  if( y==0 ){
      if( (info[x]&0x01) == 0x01 ){
          *id=8*x+y+1;
          return true;
      }
      return false;
  }
  else {
      if( ((info[x]>>y)&0x01) == 1 ){
          *id=8*x+y+1;
          return true;
      }
      else{
          return false;
      }
  }
}
/****************************************
 * @brief 将无效的ID从invailID中删除
 *
 * @param id
 *
 */
void reg_clrInvaildRFMIdToRam(uint8_t id)
{
  uint8_t x,bit;

  x=(id-1)/8;
  bit=(id-1)%8;

  HUB_API_CLEAN_BIT(invailID[x],bit);
  //if(get_net_printf_log() == true){
      DS_app_log_error("Clr IID:%d\r\n",id);
  //}
}
/*****************************************
 * @brief 将ID设置到invailID(RAM)中
 *
 */
void reg_setInvaildRFMIdToRam(uint8_t id)
{

  uint8_t buf[NODE_JOIN_INFO_LENGTH]={0};

  reg_setIdToInfo(id,buf);
  orDataLine(invailID,buf,NODE_JOIN_INFO_LENGTH);
  //if(get_net_printf_log() == true){
    DS_app_log_error("Set IID:%d\r\n",id);
  //}


}
/************************************************
 * @brief 一次性获取从info中获取有效的ID,并判断option是否为C1,如是C1,invaild置1
 *
 *
 *
 *
 * @param info
 */
void reg_getInvaildRFMId(void)
{
#if CONFIG_NVM_VERSION && HUB_DEVICE
  uint8_t x,y,id=0;
  uint8_t buf[NODE_JOIN_INFO_LENGTH]={0};
  uint8_t option=0,ret=0;

  if(getThisParam(ENbyNodeJoinInfo,buf) != 0){
      memset(invailID,0,NODE_JOIN_INFO_LENGTH);
  }
  else {
      //查找ID,读取option是否为C1,如果是C1，设置1
      for(x=0;x<NODE_JOIN_INFO_LENGTH;x++){
          for(y=0;y<8;y++){
            if( reg_getInfoId(buf,x,y,&id) == true){
                //TODO:check option
                ret = getDeviceParam(id,ENbyNodeDeviceOptionFirst,&option);
                if(option == ENbyNodeRegInfoOption_C1 && ret ==0){
                    reg_setInvaildRFMIdToRam(id);
                }
            }
          }
      }
  }
#endif
}
/***********************************************************
 * @brief 每次从RAM中只获取一个无效的ID
 *
 * @param id
 * @return true id有效;false id 无效
 */
bool reg_getInvaildFromRam (uint8_t *id)
{
  uint8_t id_x,id_bit;

  for( id_x=0;id_x<NODE_JOIN_INFO_LENGTH;id_x++){
      for(id_bit=0;id_bit<8;id_bit++){
        if( reg_getInfoId(invailID,id_x,id_bit,id) == true){
//            DS_app_log_error("invailID, x=%d,bit=%d\n",id_x,id_bit);
            return true;
        }
      }
  }

  return false;
}
/***********************************************************
 * @brief 上电从注册信息获取无效的注册信息,并保存到RAM
 *
 *
 */
void reg_getInvalid_init (void)
{
#if CONFIG_NVM_VERSION && HUB_DEVICE
  reg_getInvaildRFMId();
  reg_printfInvailID();
#endif
}
void reg_delInvalidRFMId_task (void)
{

#if CONFIG_NVM_VERSION && HUB_DEVICE
  uint8_t LocalRegister;
  uint8_t id;
  uint8_t ret;
  uint8_t option=0;
  uint8_t JoinInfo[NODE_JOIN_INFO_LENGTH];
  uint8_t id_x,id_bit;
  uint8_t nodeRegInfo[NODEREGINFO_MAX_LEN];
  uint8_t mac[MAC_ADDRESS_LENGTH]={0};
  getThisParam(ENbyLocalRegister, &LocalRegister);


  if(LocalRegister == 0){
      //TODO:每次只操作一次,
      if( reg_getInvaildFromRam(&id) == true){

          DS_app_log_error("IID:%d\r\n",id);

          ret = getDeviceParam(id,ENbyNodeDeviceOptionFirst,&option);
          if(ret == 0  && option == ENbyNodeRegInfoOption_C1){
              //TODO:对ID的option值再次做判断
              //1.删除注册无效的ID
              memset(nodeRegInfo,0,sizeof(nodeRegInfo));
              setNodeRegInfoPack(id,nodeRegInfo);

              //2.删除注册的JoinInfo
              getThisParam(ENbyNodeJoinInfo, (unsigned char *)JoinInfo);
              id_x = (id-1)/8;
              id_bit = (id-1)%8;
              HUB_API_CLEAN_BIT(JoinInfo[id_x], id_bit);
              setThisParam(ENbyNodeJoinInfo, (unsigned char *)JoinInfo);

              //3.将ID从无效注册ID RAM剔除
              reg_clrInvaildRFMIdToRam(id);
              DS_app_log_error("Del IID:%d\r\n",id);

              //4. 更新ram.mac
              getNodeJoinMac(mac, id);
              //这里的mac应该全0x00。如果有内容，意味着出错了
              for(uint8_t i = 0; i < MAC_ADDRESS_LENGTH; i++){
                  if(mac[i] != 0x00){
                      DS_app_log_error("Del error\r\n");
                      break;
                  }
              }
          }
      }
  }
#endif
}



